package com.example.maruko_course_backend.convertor;

import com.example.maruko_course_backend.dto.GrammarCategoryDto;
import com.example.maruko_course_backend.entity.Grammar;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class GrammarHelper {
  
  public static final String[] GRAMMAR_COMBINED_CATEGORIES = {
    "动词分类",
    "动词接续型-て型",
    "动词过去式-た型",
    "动词礼貌型-ます型",
    "动词能力型-れる型",
    "动词意志型-おう型",
    "动词使役型-せる型"
  };
  
  public List<GrammarCategoryDto> createGrammarCategoryDto(List<Grammar> grammars) {
    List<GrammarCategoryDto> grammarCategoryDtos = new ArrayList<>();
    for (Grammar grammar : grammars) {
      List<Grammar> targetGrammars = getTargetGrammars(grammars, grammarCategoryDtos, grammar);
      if (targetGrammars != null) {
        grammarCategoryDtos.add(generateCategoryDto(targetGrammars, grammar.getCategory()));
      }
    }
    return grammarCategoryDtos;
  }
  
  public boolean isCombinedType(String category) {
    return Arrays.asList(GRAMMAR_COMBINED_CATEGORIES).contains(category);
  }
  
  public List<List<Grammar>> getSplitGrammars(List<Grammar> grammars) {
    if (!isCombinedTypeGrammarNeedSplit(grammars.size())) {
      return Arrays.asList(grammars);
    }
    List<List<Grammar>> splitSameCategoryGrammars = new ArrayList<>();
    splitSameCategoryGrammars.add(grammars.subList(0, 3));
    splitSameCategoryGrammars.add(grammars.subList(3, grammars.size()));
    return splitSameCategoryGrammars;
  }
  
  public boolean isCombinedTypeGrammarNeedSplit(int size) {
    return size > 3;
  }
  
  private List<Grammar> getTargetGrammars(List<Grammar> grammars, List<GrammarCategoryDto> grammarCategoryDtos, Grammar currentGrammar) {
    String currentCategory = currentGrammar.getCategory();
    if (!isCombinedType(currentCategory)) {
      return Arrays.asList(currentGrammar);
    }
    if (!isContainCurrentCategory(grammarCategoryDtos, currentCategory)) {
      return getCategoryRelatedGrammars(grammars, currentCategory);
    }
    return null;
  }
  
  private GrammarCategoryDto generateCategoryDto(List<Grammar> grammars, String category) {
    return GrammarCategoryDto.builder()
      .category(category)
      .grammars(getCategoryRelatedGrammars(grammars, category))
      .build();
  }
  
  private boolean isContainCurrentCategory(List<GrammarCategoryDto> grammarCategoryDtos, String currentCategory) {
    return grammarCategoryDtos.stream().map(GrammarCategoryDto::getCategory).collect(Collectors.toList()).contains(currentCategory);
  }
  
  private List<Grammar> getCategoryRelatedGrammars(List<Grammar> grammars, String category) {
    return grammars.stream().filter(item -> category.equals(item.getCategory())).collect(Collectors.toList());
  }
  
}
